#ifndef _PORT_H
#define _PORT_H
#include "sys.h"

typedef unsigned char BOOL;

typedef unsigned char UCHAR;
typedef char CHAR;

typedef unsigned short int USHORT;
typedef short int SHORT;

typedef unsigned int ULONG;
typedef int LONG;

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define ENTER_CRITICAL_SECTION( )   			_critial_enter()
#define EXIT_CRITICAL_SECTION(_primask)   _critial_exit(_primask)

#define MB_SER_PDU_RX_END					'\r'
#define MB_SER_PDU_RX_SAT					"CTRL"
/* ----------------------- Type definitions ---------------------------------*/
typedef enum
{
    STATE_RX_INIT,              /*!< Receiver is in initial state. */
    STATE_RX_IDLE,              /*!< Receiver is in idle state. */
    STATE_RX_RCV,               /*!< Frame is beeing received. */
    STATE_RX_ERROR              /*!< If the frame is invalid. */
} eMBRcvState;

typedef enum
{
    STATE_TX_IDLE,              /*!< Transmitter is in idle state. */
    STATE_TX_XMIT               /*!< Transmitter is in transfer state. */
} eMBSndState;

typedef enum
{
    MB_PAR_NONE,                /*!< No parity. */
    MB_PAR_ODD,                 /*!< Odd parity. */
    MB_PAR_EVEN                 /*!< Even parity. */
} eMBParity;

typedef enum
{
    EV_READY,                   /*!< Startup finished. */
    EV_FRAME_RECEIVED,          /*!< Frame received. */
    EV_EXECUTE,                 /*!< Execute function. */
    EV_FRAME_SENT               /*!< Frame sent. */
} eMBEventType;

typedef enum
{
    MB_ENOERR,                  /*!< no error. */
		MB_ENOLEN,									/*!< no error. */
    MB_ENOREG,                  /*!< illegal register address. */
    MB_EINVAL,                  /*!< illegal argument. */
    MB_EPORTERR,                /*!< porting layer error. */
    MB_ENORES,                  /*!< insufficient resources. */
    MB_EIO,                     /*!< I/O error. */
    MB_EILLSTATE,               /*!< protocol stack in illegal state. */
    MB_ETIMEDOUT                /*!< timeout error occurred. */
} eMBErrorCode;

typedef enum
{
    MB_EX_NONE = 0x00,
    MB_EX_ILLEGAL_FUNCTION = 0x01,
    MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
    MB_EX_ILLEGAL_DATA_VALUE = 0x03,
    MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
    MB_EX_ACKNOWLEDGE = 0x05,
    MB_EX_SLAVE_BUSY = 0x06,
    MB_EX_MEMORY_PARITY_ERROR = 0x08,
    MB_EX_GATEWAY_PATH_FAILED = 0x0A,
    MB_EX_GATEWAY_TGT_FAILED = 0x0B
} eMBException;

typedef void* (*pxMBFunctionHandler)(uint8_t *data, uint16_t len);

typedef struct {
	char *str;
	uint16_t len;
	pxMBFunctionHandler pxHandler;
} xMBFunctionHandler;

BOOL xMBPortTimersInit(USHORT usTim1Timerout50us);
void vMBPortTimersEnable(void);
void vMBPortTimersDisable(void);


BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity);
BOOL xMBPortSerialPutByte(CHAR ucByte);
BOOL xMBPortSerialGetByte(CHAR *ucBuf);
void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable);

BOOL xMBRTUTransmitFSM(void);
BOOL xMBRTUReceiveFSM(void);
BOOL xMBRTUTimerT35Expired(void);

BOOL xMBPortEventInit(void);
BOOL xMBPortEventPost(eMBEventType eEvent);
BOOL xMBPortEventGet(eMBEventType * eEvent);

void eMBRTUStart(void);
void eMBRTUStop(void);
eMBErrorCode eMBRTUReceive(void);
eMBErrorCode eMBRTUSend(const UCHAR * pucFrame, USHORT usLength);
eMBException eMBRTUExecute(UCHAR **pucFrame, USHORT * pusLength);

eMBErrorCode eMBEnable(void);
eMBErrorCode eMBDisable(void);
eMBErrorCode eMBInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity);
eMBErrorCode eMBPoll(void);
#endif /* #ifndef _PORT_H */

